home *** CD-ROM | disk | FTP | other *** search
- #ifndef __spinlock_impl_h__
- #define __spinlock_impl_h__
-
- // Spinlock inline implementations
- // Must follow defs for threads, but precede everything else.
- //
- // Modification History:
- //
- // 28-Dec-1989 JEF
- // Add class HC_Spinlock (for sequent symmetry only). This variation of
- // a spinlock works well when there is high contention for the lock.
- // After original by raj.
- //
- #if defined(DO_SPINLOCK_INLINE) || defined(_SPINLOCK_C)
-
- /*
- * Optimized version of S_LOCK to only make the procedure call
- * if the lock is held. Would really like to use S_LOCK here,
- * but (potentially) inline functions can't handle loops.
- */
-
- SPINLOCK_INLINE
- void
- Spinlock::lock()
- {
- #ifdef ns32000
- char *lock_alm = &_alm_base[ALM_HASH(sl_lock)];
- #endif
-
- //
- // Must mark ourselves in the lock even before we acquire it.
- // Otherwise, we could hold the lock and be preempted. If we
- // were holding the lock on something that the preemption code
- // needed (or someone else, in order to ensure we run), we would
- // deadlock. Must make lock acquisition and thread in spin cs
- // marking atomic.
- //
-
- #ifndef NO_PREEMPT
- thisthread->holdingspinlock();
- #endif /* NO_PREEMPT */
-
- #ifdef ns32000
- if (sl_lock == L_LOCKED) // u lose
- (void)s_lock(&sl_lock);
- else if (*lock_alm & ALM_LOCKED) // u lose
- (void)s_lock(&sl_lock);
- else if (sl_lock == L_LOCKED) { // u lose (race condition)
- *lock_alm = ALM_UNLOCKED;
- (void)s_lock(&sl_lock);
- } else { // u win
- sl_lock = L_LOCKED;
- *lock_alm = ALM_UNLOCKED;
- }
- #else
- //
- // No ALM's in Symmetry. We use S_LOCK() and to avoid
- // another out-of-line call. Since C++ doesn't understand
- // asm-functions, must use "CC +hasmdefs.h".
- //
- // On the vax, S_LOCK is a function call to s_lock() in vax_lock.s.
- // Should probably be inline.
- //
- //cout << "regular old spinlock.lock\n"; cout.flush ();
- #ifdef PROFILE
- SLLock(sl_q);
- #endif
- (void) S_LOCK(&sl_lock);
- #endif
- }
-
-
- SPINLOCK_INLINE
- void
- Spinlock::unlock()
- {
-
- //cout << "regular old spinlock.unlock\n"; cout.flush ();
- (void) S_UNLOCK(&sl_lock);
- #ifdef PROFILE
- SLUnlock(sl_q);
- #endif
- #ifndef NO_PREEMPT
- thisthread->releasingspinlock();
- #endif /* NO_PREEMPT */
-
- }
-
- SPINLOCK_INLINE
- Spinlock::~Spinlock()
- {
- //
- // We should abort if the lock is not free. (?) XXX
- // For now just unlock it for backward compatibility.
- //
- if (testlock())
- unlock();
- #ifdef PROFILE
- SLDispose(sl_q);
- #endif
-
- }
-
-
- #endif /* DO_SPINLOCK_INLINE || SPINLOCK_C */
-
-
-
- //
- // HC_Spinlock inline implementations.
- //
- #ifdef i386
-
- SPINLOCK_INLINE
- void
- HC_Spinlock::lock()
- {
- //
- // Must mark ourselves in the lock even before we acquire it.
- // Otherwise, we could hold the lock and be preempted. If we
- // were holding the lock on something that the preemption code
- // needed (or someone else, in order to ensure we run), we would
- // deadlock. Must make lock acquisition and thread in spin cs
- // marking atomic.
- //
- #ifndef NO_PREEMPT
- thisthread->holdingspinlock();
- #endif /* NO_PREEMPT */
-
- //
- // HC_S_LOCK is an inline straight C asm function defined in
- // hc_slock_asm.h, which is pulled into the C++ C output via
- // the C++ +hasmdefs.h flag (C++ doesn't know about asm functions).
- //
- //cout << "high contention spinlock.lock\n"; cout.flush ();
- #ifdef PROFILE
- SLLock(sl_q);
- #endif
- (void) HC_S_LOCK(&sl_lock);
- }
-
-
- inline
- void
- HC_Spinlock::unlock()
- {
- //
- // HC_S_UNLOCK is an inline straight C asm function defined in
- // hc_slock_asm.h, which is pulled into the C++ C output via
- // the C++ +hasmdefs.h flag (C++ doesn't know about asm functions).
- //
-
- //cout << "high contention spinlock.unlock\n"; cout.flush ();
-
- (void) HC_S_UNLOCK(&sl_lock);
- #ifdef PROFILE
- SLUnlock(sl_q);
- #endif
-
- #ifndef NO_PREEMPT
- thisthread->releasingspinlock();
- #endif /* NO_PREEMPT */
- }
-
- #endif /* i386 */
- #endif /* __spinlock_impl_h__ */
-